﻿/*
Created by jiadong chen
https://jiadong-chen.medium.com/
*/

Shader "chenjd/BuiltIn/ForGO_AnimMapShader"
{
	Properties
	{
		_Scale("Scale", Float) = 1
		_XScale("XScale", Float) = 1
		_Color("Tint Color", Color) = (1,1,1,1)
		_Black("Dark Color", Color) = (0,0,0,0)
		_AnimData("Anim Data",Vector) = (0,0,1,1)
		[MaterialToggle]
		_AutoPlay("是否开启动画播放",Int) = 0
		_MainTex("Texture", 2D) = "white" {}
		_AnimMap("AnimMap", 2D) = "white" {}
		_AnimTime("Anim Time", Float) = 0
		_CutAlpha("Cut Alpha", Range(0.001,1.)) = 0.001

	}

		SubShader
		{
			Tags { "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Transparent" "PreviewType" = "Plane" }
			Fog { Mode Off }
			Cull Off
			ZWrite Off
			Blend One OneMinusSrcAlpha
			Lighting Off

			Pass
			{
				CGPROGRAM
				#pragma shader_feature _ _STRAIGHT_ALPHA_INPUT
				#pragma shader_feature _ _DARK_COLOR_ALPHA_ADDITIVE
				#pragma vertex vert
				#pragma fragment frag
				//开启gpu instancing
				#pragma multi_compile_instancing

				#include "UnityCG.cginc"

				struct appdata
				{
					float2 uv : TEXCOORD0;
					float4 pos : POSITION;
					float4 vertexColor : COLOR;
					UNITY_VERTEX_INPUT_INSTANCE_ID
				};

				struct v2f
				{
					float2 uvAndAlpha : TEXCOORD0;
					float4 vertex : SV_POSITION;
					float4 vertexColor : COLOR;
					UNITY_VERTEX_INPUT_INSTANCE_ID
				};

				sampler2D _MainTex;
				float4 _MainTex_ST;

				sampler2D _AnimMap;
				float4 _AnimMap_ST;
				float4 _AnimMap_TexelSize;//x == 1/width

				float _AnimLen;
				float4 _Black;
				float _CutAlpha;
				int _AutoPlay;
				float _Scale;
				float _XScale;

				UNITY_INSTANCING_BUFFER_START(Props)
					UNITY_DEFINE_INSTANCED_PROP(float4, _AnimData)	//x代表游戏时长，用来配合_Time.y使用，使每个动画在播放的时候是从0开始的，y代表动画状态，z代表动画速度,w代表z轴深度
					UNITY_DEFINE_INSTANCED_PROP(float4, _Color)		//颜色
				UNITY_INSTANCING_BUFFER_END(Props)

				float4 fragTintedColor(float4 texColor, float3 darkTintColor, float4 lightTintColor, float darkColorAlpha)
				{
					float a = texColor.a * lightTintColor.a;
					float3 texDarkColor = (texColor.a - texColor.rgb);
					float3 darkColor = texDarkColor * darkTintColor.rgb;
					float3 lightColor = texColor.rgb * lightTintColor.rgb;
					float4 fragColor = float4(darkColor + lightColor, a);
					fragColor.rgb *= fragColor.a;
					return fragColor;
				}

				float Remap(float input, float inputMin, float inputMax, float outputMin, float outputMax)
				{
					return outputMin + (input - inputMin) * (outputMax - outputMin) / (inputMax - inputMin);
				}

				v2f vert(appdata v, uint vid : SV_VertexID, float4 vertexColor : COLOR)
				{

					UNITY_SETUP_INSTANCE_ID(v);
					float4 ad = UNITY_ACCESS_INSTANCED_PROP(Props, _AnimData);
					float4 animdata = tex2Dlod(_AnimMap, float4(_AnimMap_TexelSize.x * ad.y, 0, 0, 0)); //获取存储在纹理图第一行的动画时间信息，x代表动画时长，y代表开始位置的v值，z代表结束位置的v值

					//float f = (-ad.x + _Time.y) * ad.z / animdata.x;
					float f = 0;
					if (_AutoPlay == 1)
						f = (ad.x + _Time.y) * ad.z / animdata.x;
					else
						f = (ad.x) * ad.z / animdata.x;

					f = fmod(f, 1);
					f = Remap(f, 0, 1, animdata.y + _AnimMap_TexelSize.y * 1.5, animdata.z - _AnimMap_TexelSize.y * 0.5);

					float animMap_x_col = (vid * 2 + 1.5) * _AnimMap_TexelSize.x;
					float animMap_y = f + _AnimMap_TexelSize.y * 0.5;
					float4 col = tex2Dlod(_AnimMap, float4(animMap_x_col, animMap_y, 0, 0));
					v2f o;
					o.vertexColor.a = col.a < 0 ? -1 : 1;
					float animMap_x = (vid * 2 + 0.5) * _AnimMap_TexelSize.x;

					//float4 pos = tex2Dlod(_AnimMap, float4(animMap_x, animMap_y, 0, 0)) + float4(0, 0, -ad.w / 100.0, 0);
					float4 pos = tex2Dlod(_AnimMap, float4(animMap_x, animMap_y, 0, 0)) + float4(0, 0, 0, 0);
					pos.z = 0;
					//o.vertexColor.a=pos.w!=0.?-1:1;
					pos = float4(pos.x * _Scale * _XScale, pos.y * _Scale, pos.z, pos.w);
					o.vertex = o.vertexColor.a < 0 ? 0 : UnityObjectToClipPos(pos);
					o.uvAndAlpha = o.vertexColor.a < 0 ? 0 : v.uv;
					o.vertexColor = o.vertexColor.a < 0 ? 0 : v.vertexColor * float4(col.rgb * col.a, col.a);

					UNITY_TRANSFER_INSTANCE_ID(v, o);
					return o;
				}

				fixed4 frag(v2f i) : SV_Target
				{
					UNITY_SETUP_INSTANCE_ID(i);
					float4 _c = UNITY_ACCESS_INSTANCED_PROP(Props, _Color);

					clip(i.vertexColor.a - 0.01);
					fixed4 texColor = tex2D(_MainTex, i.uvAndAlpha);
					clip(texColor.a - _CutAlpha);
					return float4((texColor * i.vertexColor).rgb * _c.xyz, texColor.a * i.vertexColor.a * _c.w);
				}
				ENDCG
			}
		}
}